package com.bckj.fastboot.flowable.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bckj.fastboot.core.lang.exception.BusinessException;
import com.bckj.fastboot.flowable.entity.FastProcess;
import com.bckj.fastboot.flowable.mapper.FastProcessMapper;
import com.bckj.fastboot.flowable.service.FastProcessService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;

@Service
public class FastProcessServiceImpl extends ServiceImpl<FastProcessMapper, FastProcess> implements FastProcessService {

    @Override
    public void deploy(MultipartFile file) {
        try {
            FastProcess process = parse(file);
            FastProcess exist = lambdaQuery().eq(FastProcess::getProcessId, process.getProcessId()).select(FastProcess::getId, FastProcess::getVersion).one();
            if (exist != null) {
                process.setId(exist.getId());
                process.setVersion(exist.getVersion() + 1);
                process.setUpdateTime(LocalDateTime.now());
                updateById(process);
            } else {
                save(process);
            }
        } catch (ParserConfigurationException e) {
            throw new BusinessException("解析配置异常");
        } catch (IOException e) {
            throw new BusinessException("IO异常");
        } catch (SAXException e) {
            throw new BusinessException("解析异常");
        }
    }

    private FastProcess parse(MultipartFile file) throws ParserConfigurationException, IOException, SAXException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Path tempFile = Files.createTempFile("bpmn", ".tmp");
        try {
            Files.copy(file.getInputStream(), tempFile, StandardCopyOption.REPLACE_EXISTING);
            Document doc = builder.parse(tempFile.toFile());
            // 解析 process 元素
            Element processElement = (Element) doc.getElementsByTagName("process").item(0);
            FastProcess process = new FastProcess();
            process.setProcessId(processElement.getAttribute("id"));
            process.setProcessName(processElement.getAttribute("name"));
            process.setContent(Files.readString(tempFile));
            return process;
        } catch (Exception e) {
            throw new BusinessException("解析异常");
        } finally {
            Files.deleteIfExists(tempFile);
        }
    }
}
